package com.netease.nim.uikit.session.fragment;

import android.Manifest;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.netease.nim.uikit.R;
import com.netease.nim.uikit.common.fragment.TFragment;
import com.netease.nim.uikit.session.SessionCustomization;
import com.netease.nim.uikit.session.actions.BaseAction;
import com.netease.nim.uikit.session.actions.ImageAction;
import com.netease.nim.uikit.session.actions.VideoAction;
import com.netease.nim.uikit.session.constant.Extras;
import com.netease.nim.uikit.session.module.Container;
import com.netease.nim.uikit.session.module.ModuleProxy;
import com.netease.nim.uikit.session.module.input.InputPanel;
import com.netease.nim.uikit.session.module.list.MessageListPanel;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;

import java.util.ArrayList;
import java.util.List;

import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.RuntimePermissions;

/**
 * 聊天界面基类
 * <p/>
 * Created by huangjun on 2015/2/1.
 */
@RuntimePermissions
public class MessageFragment extends TFragment implements ModuleProxy, InputPanel.StartRecordCallBack {

	private View rootView;

	private SessionCustomization customization;

	protected static final String TAG = "MessageActivity";

	// 聊天对象
	protected String sessionId; // p2p对方Account或者群id

	protected SessionTypeEnum sessionType;

	// modules
	protected InputPanel inputPanel;
	protected MessageListPanel messageListPanel;

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		parseIntent();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		rootView = inflater.inflate(R.layout.nim_message_fragment, container, false);
		return rootView;
	}

	/**
	 * ***************************** life cycle *******************************
	 */

	@Override
	public void onPause() {
		super.onPause();

		NIMClient.getService(MsgService.class).setChattingAccount(MsgService.MSG_CHATTING_ACCOUNT_NONE,
				SessionTypeEnum.None);
		inputPanel.onPause();
		messageListPanel.onPause();
	}

	@Override
	public void onResume() {
		super.onResume();
		messageListPanel.onResume();
		NIMClient.getService(MsgService.class).setChattingAccount(sessionId, sessionType);
		getActivity().setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); // 默认使用听筒播放
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		messageListPanel.onDestroy();
		registerObservers(false);
	}

	public boolean onBackPressed() {
		if (inputPanel.collapse(true)) {
			return true;
		}

		if (messageListPanel.onBackPressed()) {
			return true;
		}
		return false;
	}

	public void refreshMessageList() {
		messageListPanel.refreshMessageList();
	}

	private void parseIntent() {
		sessionId = getArguments().getString(Extras.EXTRA_ACCOUNT);
		sessionType = (SessionTypeEnum) getArguments().getSerializable(Extras.EXTRA_TYPE);

		customization = (SessionCustomization) getArguments().getSerializable(Extras.EXTRA_CUSTOMIZATION);
		Container container = new Container(getActivity(), sessionId, sessionType, this);

		if (messageListPanel == null) {
			messageListPanel = new MessageListPanel(container, rootView, false, false);
		} else {
			messageListPanel.reload(container, null);
		}

		if (inputPanel == null) {
			inputPanel = new InputPanel(container, rootView, getActionList(), this);
			inputPanel.setCustomization(customization);
		} else {
			inputPanel.reload(container, customization);
		}

		registerObservers(true);

		if (customization != null) {
			messageListPanel.setChattingBackground(customization.backgroundUri, customization.backgroundColor);
		}
	}

	/**
	 * ************************* 消息收发 **********************************
	 */
	// 是否允许发送消息
	protected boolean isAllowSendMessage(final IMMessage message) {
		return true;
	}

	/**
	 * ****************** 观察者 **********************
	 */

	private void registerObservers(boolean register) {
		MsgServiceObserve service = NIMClient.getService(MsgServiceObserve.class);
		service.observeReceiveMessage(incomingMessageObserver, register);

	}

	/**
	 * 消息接收观察者
	 */
	Observer<List<IMMessage>> incomingMessageObserver = new Observer<List<IMMessage>>() {
		@Override
		public void onEvent(List<IMMessage> messages) {
			if (messages == null || messages.isEmpty()) {
				return;
			}
			messageListPanel.onIncomingMessage(messages);
		}
	};


	/**
	 * ********************** implements ModuleProxy *********************
	 */
	@Override
	public boolean sendMessage(IMMessage message) {
		if (!isAllowSendMessage(message)) {
			return false;
		}

		// send message to server and save to db
		NIMClient.getService(MsgService.class).sendMessage(message, false);

		messageListPanel.onMsgSend(message);

		return true;
	}

	@Override
	public void onInputPanelExpand() {
		messageListPanel.scrollToBottom();
	}

	@Override
	public void shouldCollapseInputPanel() {
		inputPanel.collapse(false);
	}

	@Override
	public boolean isLongClickEnabled() {
		return !inputPanel.isRecording();
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		inputPanel.onActivityResult(requestCode, resultCode, data);
	}

	// 操作面板集合
	protected List<BaseAction> getActionList() {
		List<BaseAction> actions = new ArrayList<>();
		actions.add(new ImageAction());
		actions.add(new VideoAction());
//        actions.add(new LocationAction());

		if (customization != null && customization.actions != null) {
			actions.addAll(customization.actions);
		}
		return actions;
	}

	@Override
	public void start() {
		MessageFragmentPermissionsDispatcher.checkPermissionWithCheck(this);
	}

	@NeedsPermission(Manifest.permission.RECORD_AUDIO)
	public void checkPermission() {
	}
}
